package com.gitee.wsl.mathematics.geometry.api.region

import com.gitee.wsl.mathematics.coordinate.Coordinate


/** This interface defines mappings between a space and one of its subspaces.
 *
 *
 * Subspaces are the lower-dimension subsets of a space. For example,
 * in an n-dimension space, the subspaces are the (n-1) dimension space,
 * the (n-2) dimension space, and so on. This interface can be used regardless
 * of the difference in number of dimensions between the space and the target
 * subspace. For example, a line in 3D Euclidean space can use this interface
 * to map directly from 3D Euclidean space to 1D Euclidean space (ie, the location
 * along the line).
 *
 * @param <P> Point type defining the embedding space.
 * @param <S> Point type defining the embedded subspace.
</S></P> */
interface Embedding<T:Number,P: Coordinate<T, P>,S: Coordinate<T, S>> {
    /** Transform a space point into a subspace point.
     * @param pt n-dimension point of the space
     * @return lower-dimension point of the subspace corresponding to
     * the specified space point
     * @see .toSpace
     */
    fun toSubspace(pt: P): S

    /** Transform a collection of space points into subspace points.
     * @param pts collection of n-dimension points to transform
     * @return collection of transformed lower-dimension points.
     * @see .toSubspace
     */
    fun toSubspace(pts: Collection<P>): List<S> {
        return pts.map { pt: P -> this.toSubspace(pt) }
            //.collect<List<S>, Any>(java.util.stream.Collectors.toList<S>())
    }

    /** Transform a subspace point into a space point.
     * @param pt lower-dimension point of the subspace
     * @return n-dimension point of the space corresponding to the
     * specified subspace point
     * @see .toSubspace
     */
    fun toSpace(pt: S): P

    /** Transform a collection of subspace points into space points.
     * @param pts collection of lower-dimension points to transform
     * @return collection of transformed n-dimension points.
     * @see .toSpace
     */
    fun toSpace(pts: Collection<S>): List<P> {
        return pts.map { pt: S -> this.toSpace(pt) }
            //.collect<List<P>, Any>(java.util.stream.Collectors.toList<P>())
    }
}
